1. /* slfnlmul.cpp by K.Tsuru */
  2. // function ID = 210 DRADIX, BRADIX
  3. /**************************************************************
  4. SLong and SInteger classes
  5. It provides m*n using a normal method.
  6. It is fast for small figures.
  7. To get the remaindar it uses the quotient, namely a replacemant
  8. rv[i+j] = fType(w - u*rdx); <--- fType(w%rdx);
  9. The different algorithms are used for different radixes.
  10. ***************************************************************/
  11. #ifndef SN_H
  12. #include "sn.h"
  13. #endif
  14. static const char* const func = "NLLMult";
  15. SLong NLLMult(const SLong& m, const SLong& n){
  16. //check the signs
  17. int sgn = m.Sign(210)*n.Sign(210);
  18. SLong result(m.Type(), 0);
  19. if(!sgn){ // m = 0 or n = 0
  20. result.SetZero();
  21. return result;
  22. }
  23. if(m.Type() != n.Type()) m.SetError(m.RADIX_ERR, func, 210);
  24. uint mh = m.aHead, nh = n.aHead, nt = n.aTail, mt = m.aTail;
  25. if( (mh+nh+2) >= m.MaxSize() ) m.SetError( m.OVERFLOW_ERR, func, 210);
  26. result.valloc(mh+nh+2, 0); // maximum index in roop below
  27. const fType* mv = m.ReadFigures();
  28. const fType* nv = n.ReadFigures();
  29. fType* rv = result.figure.Elements();
  30. //It normalizes simultaneously.
  31. //Here (m_fig + n_fig +1) <= MaxSize-1.
  32. ulong u, w, lm, rdx = (ulong)m.Radix();
  33. register uint i, j;
  34. if(rdx == DRADIX){
  35. for(i = mt ; i <= mh ; i++){
  36. u = 0;
  37. lm = (ulong)mv[i];
  38. for(j = nt; j <= nh ; j++){
  39. w = lm*(ulong)nv[j]+(ulong)rv[i+j] + u;
  40. u = w/rdx; //carry
  41. rv[i+j] = fType(w - u*rdx); //faster than fType(w%rdx);
  42. }
  43. rv[i+j] = (fType)u;
  44. }
  45. } else {
  46. ulong rdx1 = (ulong)BRADIX1;
  47. for(i = mt ; i <= mh ; i++){
  48. u = 0;
  49. lm = (ulong)mv[i];
  50. for(j = nt; j <= nh ; j++){
  51. u += lm*(ulong)nv[j]+(ulong)rv[i+j];
  52. rv[i+j] = fType(u & rdx1); // = fType(w%rdx);
  53. u >>= BRADIX_BITS; //carry
  54. }
  55. rv[i+j] = (fType)u;
  56. }
  57. }
  58. //It desides the figure positions.
  59. uint rt = mt + nt, rh = mh + nh+1;
  60. #ifndef NDEBUG
  61. result.figure(rh);
  62. #endif
  63. while(!rv[rh]) rh--;
  64. result.aHead = rh;
  65. while(!rv[rt]) rt++;
  66. result.aTail = rt;
  67. result.SetSign( sgn );
  68. //An extra figure has been taken. It is a rare case.
  69. if( 2u*(result.aHead+1) <= result.figure.size() ) result.DoCutDown();
  70. return result;
  71. }

slfnlmul.cpp : last modifiled at 2017/03/13 14:32:00(2,258 bytes)
created at 2017/10/07 10:26:49
The creation time of this html file is 2017/11/09 14:52:03 (Thu Nov 09 14:52:03 2017).